/*
--------------------------------------------------------------------------------
				Ak-Lib. 
			 Project       	: Ak-Lib
			 Group         	: Ak-Lib R&D Team
			 Author        	: Ocean.Wang
			 Create Date 	: 05-01-2010
--------------------------------------------------------------------------------
Code Name 	:  A.K 	~v~
Description	:  Yet Another Cross-Platform Lib.
Cautions    	:
--------------------------------------------------------------------------------
Change History:
Version		: 0.1
Building 		: 05/01/10
10-05.01 first draft, build, debug and test.
--------------------------------------------------------------------------------
*/

#include "ak_htbl.h"
#include "ak_gears.h"
#include "ak_evt.h"
#include "ak_link.h"
#include "ak_obj.h"

#define _TEST_ENV_CNT 	3

/* Test for Enviorment */
static 	_t_sEvtPool 	_gTest_EvtPool;
static 	_t_ioLinkCi 	_gTest_Link[_TEST_ENV_CNT];

static 	_t_sEnv_Desc 	_gTest_Desc[_TEST_ENV_CNT];
static 	_t_sEnv 		_gTest_Env[_TEST_ENV_CNT];
static 	_t_sEvtQ 		_gTest_EvtQ[_TEST_ENV_CNT];
static 	_t_sysSemB 		_gTest_Wake[_TEST_ENV_CNT];
static 	_t_sObject		_gTest_Obj[_TEST_ENV_CNT];

static 	_t_cbentry		_gTest_Cb;
static 	unsigned int 	_gTest_RingCnt[_SEvent_Pri_Max]={
						0X100, 
						0X100, 
						0X100, 
						0X100};
static 	_t_cbentry 	*	_gTest_CbEntry[_SEvent_Pri_Max]={
						&_gTest_Cb, 
						&_gTest_Cb, 
						&_gTest_Cb, 
						&_gTest_Cb};
	
static 	void * 	Test_EnvLookUp0(unsigned int oId, unsigned int eType)
{
	return &_gTest_Obj[0];
}

static 	void * 	Test_EnvLookUp1(unsigned int oId, unsigned int eType)
{
	return &_gTest_Obj[1];
}

static 	void * 	Test_EnvLookUp2(unsigned int oId, unsigned int eType)
{
	return &_gTest_Obj[2];
}

static 	int 	Test_EvtQCb(void * pArg, long lArg, _t_sEvent * pEvent)
{
	#if 0
	unsigned char * pMsg;
	int 			i, lMsg;
	pMsg = (unsigned char *)_SEvent_MsgPtr(pEvent);
	lMsg = _SEvent_MsgLen(pEvent);
	printf("Message: %d\n", lMsg);
	for(i=0; i<lMsg; i++){
		printf("%02x ", pMsg[i]);
		if(i%16 == 15){
			printf("\n");
		}
	}
	printf("\n");
	#endif
	return 0;
}

static 	int 	Test_EnvInit(void)
{
	int i;
	_u_ipport 	ipPort;
	/* Init the Link */
	_IPPORT_GEN(&ipPort,INADDR_ANY,20000);
	
	/* Init the Desc */
	SEnv_DescInit(&_gTest_Desc[0], 0, ENV_IPC_EVTQ, ipPort, 0, Test_EnvLookUp0);
	SEnv_DescInit(&_gTest_Desc[1], 1, ENV_IPC_EVTQ, ipPort, 0, Test_EnvLookUp1);
	SEnv_DescInit(&_gTest_Desc[2], 2, ENV_IPC_EVTQ, ipPort, 0, Test_EnvLookUp2);

	/* Init the Pool */
	#if 0
	SEvtPool_InitSi(&_gTest_EvtPool, 2, 0X1000);
	#else
	SEvtPool_InitEx(&_gTest_EvtPool, 4);
	#endif
	
	/* Init the CbEntry */
	_CBENTRY_INIT(&_gTest_Cb, Test_EvtQCb, NULL, 0);

	/* Init the Env & EvtQ */
	for(i=0; i<_TEST_ENV_CNT; i++){
		SYS_SEM_B_INIT(&_gTest_Wake[i]);
		SEnv_Init(	&_gTest_Env[i], 
					&_gTest_Desc[i], 
					&_gTest_Wake[i], 
					&_gTest_EvtQ[i], 
					&_gTest_EvtPool, 
					&_gTest_Link[i]);
		SEvtQ_Init(&_gTest_EvtQ[i], &_gTest_Env[i], _gTest_CbEntry, _gTest_RingCnt);
	}
	
	return 0;
}


static 	int 	Test_TaskSche(_t_sEnv * pEnv)
{
	do{
		SYS_SEM_B_TAKE(pEnv->wake, -1);
		SEvtQ_Sche(pEnv->pEvtQ);
	}while(1);
	
	return 0;
}


static 	int 	Test_TaskPost(void)
{
	int 			i, j, len;
	unsigned int 	dEnv, dObj, eType;
	unsigned short 	pri;
	_t_sEvent 		event;
	unsigned char 	msg[0X1000];

	for(i=0; i<0X1000; i++){
		msg[i] = i;
	}
	len = 1;

	do{
		#if 1
		for(i=0; i<_TEST_ENV_CNT; i++){
		#else
		for(i=0; i<1; i++){
		#endif
			len = 2 * len;
			if(len >= 0X1000){
				len = 1;
			}
			#if 1
			for(j=0; j<_SEvent_Pri_Max; j++){
			#else
			for(j=0; j<1; j++){
			#endif
				dEnv 	= i;
				dObj 	= i;
				eType	= i;
				pri 	= j;
				_SEvent_Init(&event, dEnv, dObj, eType, pri);
				
				SEvent_PostMsg(_gTest_Env, &event, msg, len);
			}
		}
		#if 1
		SYS_SLEEP(5);
		#else
		SYS_SLEEP(1000);
		#endif
	}while(1);
	
	return 0;
}

int 	main(void)
{
	int 		i;
	_t_sysTask	task;
	Test_EnvInit();
	
	for(i=0; i<_TEST_ENV_CNT; i++){
		STASK_CRATE(task,0X100000, 100, Test_TaskSche, &(_gTest_Env[i]));
	}
	SYS_SLEEP(1000);
	Test_TaskPost();

	return 0;
}



